package com.rits.mysecrets.dao

import com.googlecode.mapperdao._
import com.rits.mysecrets.model.Secret
import com.rits.mysecrets.model.User
import com.googlecode.mapperdao.utils._

/**
 * @author kostantinos.kougios
 *
 * 16 Sep 2011
 */
abstract class SecretDao extends TransactionalSurrogateIntIdCRUD[Secret] {
	// the query dao will be injected by Daos class
	protected val queryDao: QueryDao

	// the entity for this dao is the SecretEntity which is declared
	// at the companion object
	protected val entity = SecretEntity

	private val s = SecretEntity
	private val u = UserEntity
	import Query._
	import queryDao._

	/**
	 * get all secrets for this user
	 *
	 * returns List[Secret with SurrogateIntId]
	 */
	def all(user: User) = query(
		select from s
			join (s, s.user, u)
			where s.user === user
	)

	/**
	 * get all secrets that are shared by
	 * others for this user
	 *
	 * returns List[Secret with SurrogateIntId]
	 */
	def sharedWith(user: User) = query(
		select from s
			where s.sharedWith === user
	)
}

/**
 * Mapping for  the Secret class.
 *
 * The Secret domain model class will aquire an IntId after been persisted.
 * The id is provided by the database as an autogenerated column.
 */
object SecretEntity extends Entity[Int, SurrogateIntId, Secret] {
	val id = key("id") autogenerated (_.id) // the autogenerated id mapped to "id" column and _.id property
	val title = column("title") to (_.title)
	val secret = column("secret") to (_.secret)
	val user = manytoone(UserEntity) to (_.user) // many secrets belong to 1 user 
	var sharedWith = manytomany(UserEntity) to (_.sharedWith) // many secrets can be shared amongst many users
	// instantiate the entity when it is read from the database
	def constructor(implicit m) = new Secret(title, secret, user, sharedWith) with SurrogateIntId {
		val id: Int = SecretEntity.id // the id property is added to the entity after persisting it
	}
}
